﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.ComponentModel;

namespace BaseTypesControlLib.Controls
{
    [TemplatePart(Name="PART_Track", Type=typeof(FrameworkElement))]
    [TemplatePart(Name="PART_Indicator", Type=typeof(FrameworkElement))]
    public class GaugeFieldControl:FieldControl
    {
        FrameworkElement ind, track;
        public GaugeFieldControl()
        {
            DefaultStyleKey = typeof(GaugeFieldControl);
            SizeChanged+=new SizeChangedEventHandler(GaugeFieldControl_SizeChanged);
            
        }

        void  GaugeFieldControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateIndicator();
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            track=GetTemplateChild("PART_Track") as FrameworkElement;
            ind=GetTemplateChild("PART_Indicator") as FrameworkElement;
        }
        protected override Size MeasureOverride(Size constraint)
        {
            Size sz = base.MeasureOverride(constraint);
            sz.Width = constraint.Width;
            return sz;
        }

        static GaugeFieldControl()
        {
            FrameworkPropertyMetadata fpm = new FrameworkPropertyMetadata(null,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            LabelProperty = DependencyProperty.Register("Label", typeof(string),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(true,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            EditableProperty = DependencyProperty.Register("Editable", typeof(bool),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(true,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            ReadOnlyProperty = DependencyProperty.Register("ReadOnly", typeof(bool),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(false,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            LabelAsProgressProperty = DependencyProperty.Register("LabelAsProgress", typeof(bool),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(false,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            NoTextProperty = DependencyProperty.Register("NoText", typeof(bool),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(false,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            PercentProperty = DependencyProperty.Register("Percent", typeof(bool),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(0,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange);
            PercentValueProperty = DependencyProperty.Register("PercentValue", typeof(int),
                typeof(GaugeFieldControl), fpm);

            fpm = new FrameworkPropertyMetadata(0,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange, OnMinimumPropertyChanged);
            MinimumProperty = DependencyProperty.Register("Minimum", typeof(int),
                typeof(GaugeFieldControl), fpm);
            fpm = new FrameworkPropertyMetadata(100,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange, OnMaximumPropertyChanged);
            MaximumProperty = DependencyProperty.Register("Maximum", typeof(int),
                typeof(GaugeFieldControl), fpm);
            fpm = new FrameworkPropertyMetadata(0,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsArrange, OnValuePropertyChanged);
            ValueProperty = DependencyProperty.Register("Value", typeof(int),
                typeof(GaugeFieldControl), fpm);
        }

        public string Label
        {
            get { return (string)GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }
        public static readonly DependencyProperty LabelProperty;

        public bool Editable
        {
            get { return (bool)GetValue(EditableProperty); }
            set { SetValue(EditableProperty, value); }
        }
        public static readonly DependencyProperty EditableProperty;

        public bool ReadOnly
        {
            get { return (bool)GetValue(ReadOnlyProperty); }
            set { SetValue(ReadOnlyProperty, value); }
        }
        public static readonly DependencyProperty ReadOnlyProperty;

        public bool LabelAsProgress
        {
            get { return (bool)GetValue(LabelAsProgressProperty); }
            set { SetValue(LabelAsProgressProperty, value); }
        }
        public static readonly DependencyProperty LabelAsProgressProperty;

        public bool NoText
        {
            get { return (bool)GetValue(NoTextProperty); }
            set { SetValue(NoTextProperty, value); }
        }
        public static readonly DependencyProperty NoTextProperty;

        public bool Percent
        {
            get { return (bool)GetValue(PercentProperty); }
            set { SetValue(PercentProperty, value); }
        }
        public static readonly DependencyProperty PercentProperty;

        public int PercentValue
        {
            get { return (int)GetValue(PercentValueProperty); }
            set { SetValue(PercentValueProperty, value); }
        }
        public static readonly DependencyProperty PercentValueProperty;

        public int Minimum
        {
            get { return (int)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }
        public static readonly DependencyProperty MinimumProperty;

        public int Maximum
        {
            get { return (int)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }
        public static readonly DependencyProperty MaximumProperty;

        public int Value
        {
            get { return (int)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        public static readonly DependencyProperty ValueProperty;


        private static void OnMinimumPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            GaugeFieldControl c = o as GaugeFieldControl;
            if(c!=null)
            {
                c.UpdatePercentValue();
                c.UpdateIndicator();
            }
        }
        private static void OnMaximumPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            GaugeFieldControl c = o as GaugeFieldControl;
            if (c != null)
            {
                c.UpdatePercentValue();
                c.UpdateIndicator();
            }
        }
        private static void OnValuePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            GaugeFieldControl c = o as GaugeFieldControl;
            if (c != null)
            {
                c.UpdatePercentValue();
                c.UpdateIndicator();
            }
        }
        private void UpdateIndicator()
        {
            if (track != null && ind != null)
            {
                ind.Width = ((double)PercentValue/100) * track.ActualWidth;
            }
        }
        private void UpdatePercentValue()
        {
            if (Minimum == Maximum)
            {
                PercentValue = 0;
                return;
            }
            PercentValue = (Value - Minimum) * 100 / (Maximum - Minimum);
        }

    }
}
